package com.mo.scopeprivilege.config.aspect;

import com.mo.scopeprivilege.annotation.TableInfo;
import com.mo.scopeprivilege.model.user.BaseDto;
import com.mo.scopeprivilege.model.user.MTableInfo;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @name: ParserScopeAspect
 * @description: 拼接数据权限范围
 * @author: Yang Xingfu
 * @date: 2019-10-23 17:22
 **/

@Order(1)
@Aspect
@Component
public class ParserScopeAspect extends AbstractAspect{

    @Pointcut("@annotation(com.mo.scopeprivilege.annotation.TableInfo)")
    @Override
    public void config() {

    }

    @Around("config()")
    public Object process(ProceedingJoinPoint joinPoint) throws Throwable {
        List<MTableInfo> tableInfoList = null;
        MTableInfo mTableInfo = null;
        Object[] args = null;
        Field ids = null;

        Class<?> tClass = joinPoint.getTarget().getClass();
        boolean annotationPresent = tClass.isAnnotationPresent(TableInfo.class);
        if (annotationPresent) {
            TableInfo tableInfo = tClass.getAnnotation(TableInfo.class);

            args = joinPoint.getArgs();
            for (Object arg : args) {
                ids = getField(arg.getClass(), "ids");
                if (ids != null) {
                    BaseDto baseDto = new BaseDto();
                    ids.setAccessible(true);
                    try {
                        ids.set(baseDto, new int[]{1, 2, 3});
                        int[] ints = baseDto.getIds();
                        tableInfoList = new ArrayList<>(ints.length);
                        for (int i = 0; i < ints.length; i++) {
                            mTableInfo = new MTableInfo(tableInfo.tableName(), tableInfo.alias(), tableInfo.column());
                            tableInfoList.add(mTableInfo);
                        }
                    } catch (IllegalAccessException e) {
                        ids = null;
                    }

                }

                Field mTableInfoList = getField(arg.getClass(), "MTableInfoList");
                if (mTableInfoList != null) {
                    mTableInfoList.setAccessible(true);
                    try {
                        mTableInfoList.set(arg, tableInfoList);
                    } catch (IllegalAccessException e) {
                        joinPoint.proceed(args);
                    }
                }
            }
        }
        return joinPoint.proceed(args);

    }

    public Field getField(Class<?> clazz, String fieldName) {
        Field field = null;
        try {
            field = clazz.getDeclaredField(fieldName);
        } catch (NoSuchFieldException e) {
            field = null;
        }

        return field == null && !clazz.getSuperclass().equals(Object.class) ? getField(clazz.getSuperclass(), fieldName) : field;
    }
}
